From: Kai Huang Date: Mon, 4 May 2015 10:10:41 +0000 (+0200) Subject: log-dirty: add new paging_mark_gfn_dirty X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~3359 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https://%22%22/%22http:/www.example.com/cgi/%22https:/%22%22?a=commitdiff_plain;h=33db5c0bacbece3769a619161e133ebfb9378230;p=xen.git log-dirty: add new paging_mark_gfn_dirty PML logs GPA in PML buffer. Original paging_mark_dirty takes MFN as parameter but it gets guest pfn internally and use guest pfn to as index for looking up radix log-dirty tree. In flushing PML buffer, calling paging_mark_dirty directly introduces redundant p2m lookups (gfn->mfn->gfn), therefore we introduce paging_mark_gfn_dirty which is bulk of paging_mark_dirty but takes guest pfn as parameter, and in flushing PML buffer we call paging_mark_gfn_dirty directly. Original paging_mark_dirty then simply is a wrapper of paging_mark_gfn_dirty. Signed-off-by: Kai Huang Acked-by: Tim Deegan --- diff --git a/xen/arch/x86/mm/paging.c b/xen/arch/x86/mm/paging.c index b54d76aead..77c929bf58 100644 --- a/xen/arch/x86/mm/paging.c +++ b/xen/arch/x86/mm/paging.c @@ -266,24 +266,17 @@ static int paging_log_dirty_disable(struct domain *d, bool_t resuming) return ret; } -/* Mark a page as dirty */ -void paging_mark_dirty(struct domain *d, unsigned long guest_mfn) +/* Mark a page as dirty, with taking guest pfn as parameter */ +void paging_mark_gfn_dirty(struct domain *d, unsigned long pfn) { - unsigned long pfn; - mfn_t gmfn; int changed; mfn_t mfn, *l4, *l3, *l2; unsigned long *l1; int i1, i2, i3, i4; - gmfn = _mfn(guest_mfn); - - if ( !paging_mode_log_dirty(d) || !mfn_valid(gmfn) || - page_get_owner(mfn_to_page(gmfn)) != d ) + if ( !paging_mode_log_dirty(d) ) return; - /* We /really/ mean PFN here, even for non-translated guests. */ - pfn = get_gpfn_from_mfn(mfn_x(gmfn)); /* Shared MFNs should NEVER be marked dirty */ BUG_ON(SHARED_M2P(pfn)); @@ -351,6 +344,24 @@ out: return; } +/* Mark a page as dirty */ +void paging_mark_dirty(struct domain *d, unsigned long guest_mfn) +{ + unsigned long pfn; + mfn_t gmfn; + + gmfn = _mfn(guest_mfn); + + if ( !paging_mode_log_dirty(d) || !mfn_valid(gmfn) || + page_get_owner(mfn_to_page(gmfn)) != d ) + return; + + /* We /really/ mean PFN here, even for non-translated guests. */ + pfn = get_gpfn_from_mfn(mfn_x(gmfn)); + + paging_mark_gfn_dirty(d, pfn); +} + /* Is this guest page dirty? */ int paging_mfn_is_dirty(struct domain *d, mfn_t gmfn) diff --git a/xen/include/asm-x86/paging.h b/xen/include/asm-x86/paging.h index 53de7154c2..c99324cf82 100644 --- a/xen/include/asm-x86/paging.h +++ b/xen/include/asm-x86/paging.h @@ -156,6 +156,8 @@ void paging_log_dirty_init(struct domain *d, /* mark a page as dirty */ void paging_mark_dirty(struct domain *d, unsigned long guest_mfn); +/* mark a page as dirty with taking guest pfn as parameter */ +void paging_mark_gfn_dirty(struct domain *d, unsigned long pfn); /* is this guest page dirty? * This is called from inside paging code, with the paging lock held. */